﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections;
using System.Collections.Generic;
using TravelWallet.Types;
using System.Linq;
using System.IO.IsolatedStorage;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Resources;
using System.IO;

namespace TravelWallet
{
    public partial class LocalStorageModel : IStorageModel
    {
        private List<WalletItem> walletItems;

        public List<WalletItem> WalletItems
        {
            get { return walletItems; }
            set { walletItems = value; }
        }
        private List<Program> programs;

        public List<Program> Programs
        {
            get { return programs; }
            set { programs = value; }
        }
        private long lastID = 1;
        private const string fileName = "travelwallet.txt";

        public LocalStorageModel()
        {
            walletItems = new List<WalletItem>();
            programs = new List<Program>();
        }

        public Program AddProgram(string name, string programName, ProgramCategory category)
        {
            Program program = new Program();
            program.Name = name;
            program.ProgramName = programName;
            program.Category = category;
            program.ProgramID = GetNextID();
            lastID++;

            programs.Add(program);
            return program;
        }

        public void AddProgramToList(long id, ProgramCategory category, string name, string programName, PartnerGroup partnerGroup)
        {
            Program program = new Program();
            program.ProgramID = id;
            lastID = id;
            program.ProgramName = programName;

            program.Name = name;
            program.Category = category;
            program.PartnerGroup = partnerGroup;

            programs.Add(program);
        }

        public long GetNextID()
        {
            long retVal = lastID;
            bool isDone = false;

            while (!isDone)
            {
                if (this.programs.Select(t => t.ProgramID).Contains(retVal))
                {
                    //id is in use, need to increment and try again
                    retVal++;
                    isDone = false;
                }
                else
                {
                    //id is not in use
                    isDone = true;
                }
            }
            return retVal;
        }
        public static void WriteToDisk(LocalStorageModel storageModel)
        {

            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (var stream = new IsolatedStorageFileStream(fileName, System.IO.FileMode.Create, System.IO.FileAccess.Write, storage))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(LocalStorageModel));
                    serializer.Serialize(stream, storageModel);

                
                }
            }


        }



        public static LocalStorageModel CreateStorageModel()
        {

            LocalStorageModel retVal = null;
            using (var storage = IsolatedStorageFile.GetUserStoreForApplication())
            {

                using (var stream = new IsolatedStorageFileStream(fileName, System.IO.FileMode.OpenOrCreate, storage))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(LocalStorageModel));
                    try
                    {
                        LocalStorageModel pointProgramData = LoadPrograms();
                        retVal = (LocalStorageModel)serializer.Deserialize(stream);
                       // retVal.Programs = pointProgramData.Programs;

                        //at this point we have loaded all the programs from our stored xml
                        //file lets go back to the original file to ensure that we get any new
                        //programs that might have been installed by an update
                        foreach (Program p in pointProgramData.Programs)
                        {
                            var result = retVal.Programs.Where(pr => pr.Name == p.Name && pr.Category == p.Category);
                            if (result == null ||
                                result.Count() == 0)
                            {
                                //there is a file in the xml that isnt in our deserialized version
                                //we should add it
                                retVal.Programs.Add(p);
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        //retVal = new LocalStorageModel();
                        retVal = LoadPrograms();
                    }
                }

            }

            return retVal;
        }



        public System.Collections.Generic.List<Types.WalletItem> GetWalletItems(long userID)
        {
            return walletItems;
        }

        public System.Collections.Generic.List<Types.WalletItem> GetWalletItems(long userID, Types.ProgramCategory category)
        {
            throw new NotImplementedException();
        }

        public long AddWalletItem(Types.WalletItem newItem)
        {
            long id = GetNewId();
            newItem.ID = id;
            walletItems.Add(newItem);
            return id;

        }

        public void DeleteWalletItem(long walletItemID)
        {
            WalletItem item = GetWalletItem(walletItemID);
            walletItems.Remove(item);
        }

        public void EditWalletItem(long walletItemID, Types.WalletItem newItem)
        {
            walletItems.Remove(newItem);
            walletItems.Add(newItem);

        }


        public System.Collections.Generic.List<Types.Program> GetPrograms()
        {
            return programs;
        }

        private WalletItem GetWalletItem(long id)
        {
            var a = from item in walletItems
                    where item.ID == id
                    select item;

            if (a != null && a.Count() == 1)
            {
                return a.First<WalletItem>();
            }
            else
            {
                throw new Exception(string.Format("LocalStorageModel.GetWalletItem: Cannot find item with id: {0} in store", id));
            }
        }

        private long GetNewId()
        {
            long retVal = 0;

            foreach (WalletItem item in walletItems)
            {
                if (item.ID > retVal)
                {
                    retVal = item.ID;
                }
            }

            retVal++;
            return retVal;
        }


        public void Close()
        {
            LocalStorageModel.WriteToDisk(this);
        }


 
    }
}
